// 使用Exceed作为ajax库，文档见 http://web.npm.alibaba-inc.com/package/exceed
import Exceed from 'exceed';
import { Message } from '@teamix/ui';
import apimapCodeup from './apimapCodeup';
import apimapUILess from './apimapUILess';
import { ENUM, rootPath } from '../constants';

// 对apimap做一次封装，最简只需定义id和url字段
import intl from '../../locale';

function apimapCreator(apimapArr) {
  // 在这里可以对url做一些统一处理，如加前缀，加headers
  return apimapArr.map((option) => {
    let url;
    if (/^http/.test(option.url)) {
      url = option.url;
    } else {
      // 非 get 请求加上 csrf
      let postUrlTails = '';
      if (option.method && option.method !== 'get' && window.FORCE.csrfTokenName) {
        if (option.url.includes('?')) {
          postUrlTails = `&${window.FORCE.csrfTokenName}=${window.FORCE.csrfToken}`;
        } else {
          postUrlTails = `?${window.FORCE.csrfTokenName}=${window.FORCE.csrfToken}`;
        }
      }

      url = `${rootPath}${option.noApiPrefix ? '' : '/api'}${
        option.noVersionPrefix ? '' : option.version || ENUM.api_version.V3
      }${option.url}${postUrlTails}`;
    }

    // 所有 post、put 请求统一 contentType: 'application/json'
    let { contentType } = option;
    if (!contentType && (option.method === 'post' || option.method === 'put')) {
      contentType = 'application/json';
    }

    return {
      name: option.name || option.id,
      id: option.id,
      method: option.method || 'get',
      type: option.type || 'json',
      headers: option.headers,
      urls: {
        local: url,
      },

      contentType,
      noErrorToast: option.noErrorToast,
      withCredentials: option.withCredentials,
    };
  });
}

const exceed = new Exceed({
  ENV: 'local',
});

exceed.use(apimapCreator([...apimapCodeup, ...apimapUILess]));

exceed.interceptors.response.success.push((response, config, originRequest) => {
  let linkHeader = null;
  const allResponseHeaders =
    originRequest.getAllResponseHeaders && originRequest.getAllResponseHeaders();
  if (allResponseHeaders && allResponseHeaders.indexOf('link') > -1) {
    linkHeader = originRequest.getResponseHeader && originRequest.getResponseHeader('link');
  }
  // 若result是数组的话，向第一个元素塞分页信息
  if (Array.isArray(response)) {
    let amount = response.length;
    if (linkHeader) {
      let pair;
      linkHeader.split(',').forEach((e) => {
        pair = e.split(';');
        if (pair.length === 2) {
          if (pair[1].includes('rel="amount"')) {
            const num = /<(\d+)>/.exec(pair[0].trim())[1];
            if (num) {
              amount = parseInt(num);
            }
            return false;
          }
        }
      });
    }

    response.unshift({
      amount,
    });
  }
});

exceed.interceptors.response.error.push((response, msg, t, config) => {
  // noErrorToast 标识无需错误提示toast
  if (config.noErrorToast) {
    return;
  }
  // 加密库禁用kms时返回412,页面直接显示错误页。前端不弹toast
  if (response.status === 412) {
    return;
  }
  if (response.status !== 200) {
    try {
      const responseText = JSON.parse(response.responseText);
      if (responseText.message) {
        // Unauthorized 为登录过期，吊顶会弹弹窗，不需再弹Message
        if (responseText.message === 'Unauthorized') {
          return;
        }
        Message.error({
          title: <div dangerouslySetInnerHTML={{ __html: responseText.message }} />,
        });
      } else {
        Message.error({
          title: responseText.errorCode,
        });
      }
    } catch (e) {
      if (response.status === 0) {
        Message.error({
          title: '无法连接到服务器，请刷新页面重试或联系工单支持',
        });
      } else {
        Message.error({
          title: intl.get({
            id: 'code-assets.utils.apimap.TheSystemIsBusyPlease',
            defaultMessage: '系统繁忙，请稍后重试',
          }),
        });
      }
    }
  }
});

// 封装forceFetch方法，以处理返回为数组的请求
const originalFetch = (options) =>
  new Promise((resolve) => {
    resolve(exceed.fetch(options));
  });
window.API_CACHE = {};
exceed.forceFetch = (options) =>
  new Promise((resolve) => {
    // 若 cache: true，则对接口进行缓存，用于解决多处调同一接口重复调用问题
    if (options.cache) {
      if (window.API_CACHE[options.api]) {
        resolve(window.API_CACHE[options.api]);
        return;
      }
    }

    const FetchPromise = originalFetch(options).then((originalResult) => {
      let newResult = originalResult;

      // result是数组的话，取第一个作为分页信息
      // if (Array.isArray(originalResult) && originalResult.length > 1 && originalResult[0].amount) {
      if (Array.isArray(originalResult)) {
        const pageObj = originalResult.shift();
        newResult = {
          amount: pageObj.amount,
          list: originalResult,
        };
      }

      if (options.cache) {
        window.API_CACHE[options.api] = newResult;
      }

      return newResult;
    });

    if (options.cache) {
      window.API_CACHE[options.api] = FetchPromise;
    }

    resolve(FetchPromise);
  });

export default exceed;
